package com.pine.manager.pineframework.trigger.impl;

import cn.hutool.core.collection.CollUtil;
import com.pine.common.beans.exception.BusinessException;
import com.pine.common.beans.exception.ExceptionCodeEnum;
import com.pine.common.beans.request.BatchIdRequest;
import com.pine.common.beans.response.DeleteResponse;
import com.pine.common.trigger.AbstractTriggerTemplate;
import com.pine.common.trigger.TriggerContext;
import com.pine.common.trigger.TriggerType;
import com.pine.manager.core.BaseManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 抽闲批量删除触发器模版
 *
 * @author pine manage
 * @since 2024-08-14
 */
public abstract class AbstractBatchDeleteTriggerTemplate<Manager extends BaseManager<?, ?, Long, ?, ?, ?>> extends AbstractTriggerTemplate<BatchIdRequest<Long>, DeleteResponse> {

    @Autowired
    protected Manager manager;

    public AbstractBatchDeleteTriggerTemplate(TriggerType triggerType) {
        super(triggerType);
    }

    @Override
    protected void before(TriggerContext<BatchIdRequest<Long>> triggerContext) {
        BatchIdRequest<Long> triggerRequest = triggerContext.getTriggerRequest();
        List<Long> ids = triggerRequest.getIds();
        if (CollUtil.isEmpty(ids)) {
            throw new BusinessException(ExceptionCodeEnum.PARAM_NOT_NULL);
        }
    }

    /**
     * 触发
     *
     * @param triggerContext 触发上下文
     * @return 触发结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public DeleteResponse trigger(TriggerContext<BatchIdRequest<Long>> triggerContext) {
        BatchIdRequest<Long> triggerRequest = triggerContext.getTriggerRequest();
        List<Long> ids = triggerRequest.getIds();

        // 如果列表很大，考虑分批删除以减轻数据库压力
        int batchSize = 100; // 每批处理100条
        boolean deleted = true;

        // 分批次删除
        for (int i = 0; i < ids.size(); i += batchSize) {
            int toIndex = Math.min(i + batchSize, ids.size());
            List<Long> batchKeys = ids.subList(i, toIndex);

            deleted = deleted && this.manager.deleteById(batchKeys);
        }

        DeleteResponse deleteResponse = new DeleteResponse();
        deleteResponse.setDeleted(deleted ? DeleteResponse.DELETED_SUCCESS : DeleteResponse.DELETED_FAIL);
        return deleteResponse;
    }
}
